package com.example.common.utils;

import com.alibaba.fastjson.JSONObject;
import org.springframework.util.DigestUtils;
import sun.misc.BASE64Decoder;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class AesUtil {

    private static final String SECRET_KEY = "abcdsxyzhkj12345";

    private static final String KEY = DigestUtils.md5DigestAsHex((SECRET_KEY).getBytes()).toUpperCase();

    /**
     * 数据加密
     * @param data 需要加密数据
     * @return  加密结果
     * @throws Exception 异常
     */
    public static String encrypt(Object data) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        String content = JSONObject.toJSONString(data);
        SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);
        byte[] encryptedByteValue = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedByteValue);
    }

    /**
     * 默认解密数据转为String类型
     * @param content   加密数据
     * @return
     * @throws NoSuchPaddingException
     * @throws IllegalBlockSizeException
     * @throws IOException
     * @throws NoSuchAlgorithmException
     * @throws BadPaddingException
     * @throws InvalidKeyException
     */
    public static String decrypt(String content) throws NoSuchPaddingException, IllegalBlockSizeException, IOException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
        return decrypt(content, String.class);
    }

    /**
     * AES解密
     * @param content 需要解密数据
     * @param clazz 解密结果转换类
     * @return  对应数据结果
     * @param <T>  泛型
     * @throws Exception 异常
     */
    public static <T> T decrypt(String content, Class<T> clazz) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, keySpec);
        byte[] encryptedValue = new BASE64Decoder().decodeBuffer(content);
        byte[] original = cipher.doFinal(encryptedValue);
        String dataStr = new String(original, StandardCharsets.UTF_8);
        return JSONObject.parseObject(dataStr, clazz);
    }
}
